/**
  ******************************************************************************
  * File Name          : ModbusMaster.c
  * Description        :Modbus Master 协议处理
  *
  ******************************************************************************
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/

#include "ModbusMaster.h"


/* define ------------------------------------------------------------------*/

uint16_t	RECIVE[16];


sModbusMasterSetDef	master=
{
	1,
	1,
	3,
	0,
	MASTERUINT16
};

/* Exported typedef ------------------------------------------------------------------*/




/* struct data ------------------------------------------------------------------*/

static	uint16_t	MasterState=MASTER_STATE_IDLE;

static	uint8_t		MasterBuf[MASTERSIZE]={0};

/** MasterBufCODLFH设备指令表 **/

/* Function ------------------------------------------------------------------*/

static void MasterSend(uint8_t	*AtBuf,uint16_t	AtBufLen)
{
	/*发送AT指令*/
	UartSend(&huart1,AtBuf,AtBufLen);
}


/*
*	ModbusMasterSendWaitReply						MODBUS数据处理函数
*	sModbusMasterSetDef	*MasterData,		MODBUS指令结构体
*	tUartRxBufDef	*Reply,								从站数据返回，串口接收结构体
*	void *Register,uint16_t	timeout,uint16_t	repnum	解析后的数据存储地址，超时时间（ms），重试次数
*	
*/
uint16_t	ModbusMasterSendWaitReply(sModbusMasterSetDef	*MasterData,	tUartRxBufDef	*Reply,
																		void *Register,uint16_t	timeout,uint16_t	repnum)
{
	uint16_t result = 0;
	static uint16_t	toutnum=0;
	switch(MasterState)
	{
		case	MASTER_STATE_IDLE:
		{
			MasterState=MASTER_STATE_SEND;
			result=MASTER_STATE_SEND;
			break;
		}
		case	MASTER_STATE_SEND:
		{
			// MODBUS MASTER 帧组帧发送
			MasterBuf[0]=MasterData->SlaveId&0xff;
			MasterBuf[1]=MasterData->SlaveCmd&0xff;
			MasterBuf[2]=MasterData->SlaveAddr>>8;
			MasterBuf[3]=MasterData->SlaveAddr&0xff;
			
			if(5>=MasterData->SlaveType)
			{
				MasterBuf[4]=0;
				MasterBuf[5]=1;
			}
			else
			{
				MasterBuf[4]=0;
				MasterBuf[5]=2;
			}
			
			uint16_t	Crc=ModbusCrcCheck(MasterBuf,6);
			MasterBuf[6]=Crc&0xff;
			MasterBuf[7]=Crc>>8;
					
			MasterSend(MasterBuf,8);
			
			Start_Tick(1);
		}
		case MASTER_STATE_WAIT:
		{
			if(0==tickstart[1].start)Start_Tick(1);//启动定时器
			if((tickstart[1].start)&&(tickstart[1].time>timeout))//数据返回超时
			{
				Stop_Tick(1);
				if(toutnum++<repnum)
				{
					MasterSend(MasterBuf,8);
					MasterState=MASTER_STATE_WAIT;
				}
				else
				{
					MasterState=MASTER_STATE_WAIT;
				}
			}
			else if(0!=Reply->Start)//从站数据返回
			{
				Stop_Tick(1);
				//数据正常返回
				if(0==ModbusCrcCheck(Reply->Buf,Reply->Size))
				{
					switch(MasterData->SlaveType)
					{
						case MASTERUINT16:
						{
							uint16_t	*temp=Register;
							*temp=Reply->Buf[3];*temp>>=8;
							*temp|=Reply->Buf[4];
							break;
						}
						case MASTERUINT16_X10:
						{
							uint16_t	temp=0;
							float *flttemp=Register;
							
							temp=Reply->Buf[3];temp>>=8;
							temp|=Reply->Buf[4];
							
							*flttemp=(float )temp/10;
							break;
						}
						case MASTERUINT16_X100:
						{
							uint16_t	temp=0;
							float *flttemp=Register;
							
							temp=Reply->Buf[3];temp>>=8;
							temp|=Reply->Buf[4];
							*flttemp=(float )temp/100;
							break;
						}
						case MASTERINT16:
						{
							int16_t	*temp=Register;
							*temp=Reply->Buf[3];*temp>>=8;
							*temp|=Reply->Buf[4];
							break;
						}
						case MASTERINT16_X10:
						{
							int16_t	temp=0;
							float *flttemp=Register;
							
							temp=Reply->Buf[3];temp>>=8;
							temp|=Reply->Buf[4];
							
							*flttemp=(float )temp/10;
							break;
						}
						case MASTERINT16_X100:
						{
							int16_t	temp=0;
							float *flttemp=Register;
							
							temp=Reply->Buf[3];temp>>=8;
							temp|=Reply->Buf[4];
							*flttemp=(float )temp/100;
							break;
						}
						case MASTERUINT32:
						{
							uint32_t *uinttemp=Register;
							
							*uinttemp =Reply->Buf[3];*uinttemp>>=8;
							*uinttemp|=Reply->Buf[4];*uinttemp>>=8;
							*uinttemp|=Reply->Buf[5];*uinttemp>>=8;
							*uinttemp|=Reply->Buf[6];
							break;
						}
						case MASTERINT32:
						{
							int32_t *inttemp=Register;
							
							*inttemp=Reply->Buf[3];*inttemp>>=8;
							*inttemp|=Reply->Buf[4];*inttemp>>=8;
							*inttemp|=Reply->Buf[5];*inttemp>>=8;
							*inttemp|=Reply->Buf[6];
							break;
						}
						case MASTERFLOAT_CDAB:
						{
							float *flttemp=Register;
							flttemp[0]=Reply->Buf[5];
							flttemp[1]=Reply->Buf[6];
							flttemp[2]=Reply->Buf[3];
							flttemp[3]=Reply->Buf[4];
							break;
						}
						case MASTERFLOAT_ABCD:
						{
							float *flttemp=Register;
							flttemp[0]=Reply->Buf[3];
							flttemp[1]=Reply->Buf[4];
							flttemp[2]=Reply->Buf[5];
							flttemp[3]=Reply->Buf[6];
							break;
						}
						default:break;
					}
				}
			}
			break;
		}
		case MASTER_STATE_TIMEOUT:
		{
			result=MASTER_STATE_IDLE;
			break;
		}
		case MASTER_STATE_RECIVE_DOWN:
		{
			result=MASTER_STATE_IDLE;
			break;
		}
		default:
		{
			result=MASTER_STATE_IDLE;
			break;
		}
	}
	
	
	return result;
}



/*

	ModbusMasterTask													MODBUS MASTER 数据处理进程，从串口获取从机数据并存储到指定位置

*/


void ModbusMasterTask(void)
{
	if(0!=master.Status)
	{
		if(0!=ModbusMasterSendWaitReply(&master,&Uart1RxBuf,RECIVE,3000,3))
		{
			;
		}
	}
	return;
}












/************************ (C) COPYRIGHT INLEEQ *****END OF FILE****/
